function BaseRouter() {
    var RouterSubscribe = instanceFactory(Subscribe);
    this.router = new RouterSubscribe();
    this.routes = [];
    this.routesReg = [];
}

BaseRouter.prototype.publish = function (path, fullpath) {
    var notFound = true;
    for (var regs = this.routesReg, i = regs.length - 1, cur; cur = regs[i]; i--) {
        cur.test(path) && (this.router.publish(this.routes[i], fullpath), i = -1, notFound = false);
    }
    if (notFound) {
        this.router.publish('/404', '/404');
    }
}

BaseRouter.prototype.addRoute = function (routeConfig) {
    var path = routeConfig['path'],
        render = routeConfig['render'],
        rewrite = routeConfig['rewrite'];

    path && this.routes.push(path); //这里应该去重
    path && this.routesReg.push(this.getRouteReg(path)); //这里应该去重
    if (rewrite) {
        this.router.subscribe(path, this.rewriteTo(rewrite));
        return;
    }
    if (isFun(render)) {
        this.router.subscribe(path, render);
        return;
    } else {
        if (!render) {
            return false;
        }
        isArray(render) && render.forEach(r => {
            r['path'] = path + r['path'];
            this.addRoute(r);
        });
    }
}

BaseRouter.prototype.addLinkEvent = function () {
    var _that = this;
    document.addEventListener('click', function (e) {
        e = e || event;
        var target = e.target;
        if (target.nodeName === 'A' && getAttribute('type', target) === 'routerLink') {
            e.stopPropagation();
            e.preventDefault();
            var href = getAttribute('href', target);
            _that.jumpTo(href);
            return false;
        }
    });
}

BaseRouter.prototype.setRoutes = function (routesConfig) {
    for (var route in routesConfig) {
        this.addRoute(routesConfig[route]);
    }
    this.init();
}

BaseRouter.prototype.rewriteTo = function rewriteTo(path) {
    var _that = this;
    return function () {
        _that.jumpTo(path);
    }
}

BaseRouter.prototype.getRoutePath = function getRoutePath(fullpath) {
    return fullpath.replace(/(\?|\#|\&).*/, '');
}

BaseRouter.prototype.getRouteReg = function getRouteReg(routePath) {
    return new RegExp('^' + routePath.replace(/\:[^\/]+/g, '.*?').replace(/\//g, '\\/') + '$');
}